首页>>百科常识

java中hashcode什么时候用?怎么用? 求详解

今天宠物迷的小编给各位宠物饲养爱好者分享hashcode作用的宠物知识,其中也会对java中hashcode什么时候用?怎么用? 求详解(为什么要有hashcode方法)进行专业的解释,如果能碰巧解决你现在面临的宠物相关问题,别忘了关注本站哦,现在我们开始吧!

java中hashcode什么时候用?怎么用? 求详解

有许多人学了很长时间的Java,但一直不明白hashCode方法的作用,
我来解释一下吧。首先,想要明白hashCode的作用,你必须要先知道Java中的集合。  
总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set。
你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。
那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?
这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。
也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。
于是,Java采用了哈希表的原理。哈希(Hash)实际上是个人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。
哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。如果详细讲解哈希算法,那需要更多的文章篇幅,我在这里就不介绍了。
初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。
这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。
如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,
就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。
所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
所以,Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同;2、如果两个对象的hashCode相同,它们并不一定相同 上面说的对象相同指的是用eqauls方法比较。
你当然可以不按要求去做了,但你会发现,相同的对象可以出现在Set集合中。同时,增加新元素的效率会大大下降。hashcode这个方法是用来鉴定2个对象是否相等的。 那你会说,不是还有equals这个方法吗? 不错,这2个方法都是用来判断2个对象是否相等的。但是他们是有区别的。 一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等 了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以 认为只要姓名和性别相等,那么就说这2个对象是相等的。 hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode 这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相 当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要 覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名 的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。 要从物理上判断2个对象是否相等,用==就可以了。

java中hashcode什么时候用?怎么用? 求详解

重写hashcode和equals 有什么作用

为了阐明其作用,先来假设有如下一个Person类。
classPerson
{
publicPerson(String name, intage)
{
this.name = name;
this.age = age;
}

privateString name;
privateint age;

publicString getName()
{
returnname;
}

publicvoid setName(String name)
{
this.name = name;
}

publicint getAge()
{
returnage;
}

publicvoid setAge(intage)
{
this.age = age;
}

publicString toString()
{
return"{" + name + ", " + age + "}";
}
}
现在有很多Person类的对象需要存储,很自然联想到用HashSet来存储,于是乎,写了下面的程序来测试一下:

importjava.util.*;

publicclass HashSetDemo
{
publicstatic void main(String[] args)
{
Collection set = newHashSet();
set.add(newPerson("张三",21));
set.add(newPerson("李四",19));
set.add(newPerson("王五",22));
set.add(newPerson("张三",21));

sop(set);
}

privatestatic void sop(Collection set)
{
Iterator it = set.iterator();
while(it.hasNext())
{
Person p = it.next();
System.out.println(p.toString());
}
}
}
其实,在往HashSet集合放置元素时,会根据其hashCode来判断两个元素是否一样,如果是一样,这后者覆盖前者。而hashCode默认是比较其地址值。
为了达到只存放一个的目的,我们必须重写hashCode方法,当然与其紧密联系的equals方法也要重写,新的Person类如下:
classPerson
{
publicPerson(String name, intage)
{
this.name = name;
this.age = age;
}

privateString name;
privateint age;

publicString getName()
{
returnname;
}

publicvoid setName(String name)
{
this.name = name;
}

publicint getAge()
{
returnage;
}

publicvoid setAge(intage)
{
this.age = age;
}

publicString toString()
{
return"{" + name + ", " + age + "}";
}

publicint hashCode()
{
returnname.hashCode() + age * 10;
}

publicboolean equals(Object obj)
{
if(!(obj instanceofPerson))
thrownew ClassCastException("类型不匹配");
Person p = (Person)obj;
returnthis.name.equals(p.getName()) && this.age == p.getAge();
}
}

java hashcode是什么类型

@Overridepublic int hashCode() { return super.hashCode();}返回值是int 一般返回的是物理内存地址,可以自定义返回值;重写hashCode()方法即可。

请教java中的hashCode()方法 具体是什么意思?作用?一般用在什么地方?

返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常规协定是:

在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)

java中hashcode()方法有什么作用呢?最好举个例子啊!

hashcode这个方法是用来鉴定2个对象是否相等的。
那你会说,不是还有equals这个方法吗?

不错,这2个方法都是用来判断2个对象是否相等的。但是他们是有区别的。

一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了。

请教unity中mesh.tangent是什么作用,一般用在什么地方

unity 官网的参考文档就有写。 也就是你unity 里面help - scripting reference, 打开官方脚本参考, 在class下找到Mesh类。

java中hashcode()方法有什么作用呢?最好举个例子啊!

hashcode这个方法是用来鉴定2个对象是否相等的。
那你会说,不是还有equals这个方法吗?

不错,这2个方法都是用来判断2个对象是否相等的。但是他们是有区别的。

一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了。

哈希码的介绍

哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。

JAVA中重写equals方法为什么要重写hashcode方法说明

重写hashCode()时最重要的原因就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值。如果在将一个对象用put()方法添 加进HashMap时产生一个hashCode()值,而用get()取出时却产生了另外一个 hashCode()值,那么就无法重新取得该对象了。所以,如果你的hashCode()方法依赖于对象中易变的数据,那用户就要小心了,因为此数据发 生变化时,hashCode()就会产生一个不同的hash码,相当于产生了一个不同的“键”。 Object的hashCode()方法,返回的是当前对象的内存地址。下次如果我们需要取一个一样的“键”对应的键值对的时候,我们就无法得到一样的 hashCode值了。因为我们后来创建的“键”对象已经不是存入HashMap中的那个内存地址的对象了。 我们看一个简单的例子,就能更加清楚的理解上面的意思。假定我们写了一个类:Person (人),我们判断一个对象“人”是否指向同一个人,只要知道这个人的***号一直就可以了。 先来个没有重写Code类的hashcode()的例子吧,看看是什么效果: package com****; import java.util.HashMap; /** * ***类 * * @author ZYD * */ public class Code { /** * ***号码,一旦确定就不能更改 */ private final int id; public int getId() { return id; } /** * 通过构造方法确定***号码 * * @param id */ public Code(int id) { this.id = id; } /** * 重写equals()方法 */ public boolean equals(Object o) { // 如果地址一样,则两个对象相同 if (this == o) { return true; } // 如果两个对象是同一类型,则比较其属性值是否都相同。如果都相同,则说明两个对象也相同;否则,说明这两个对象不相同。 if (o instanceof Code) { Code co = (Code) o; boolean b = (co.id == this.id); return b; } return false; } /** * 重写toString()方法 */ public String toString() { return "【***】:" + id; } /** * 测试 * @param args */ public static void main(String[] args) { HashMap map = new HashMap(); Person p1 = new Person(new Code(10001),"张三"); Person p2 = new Person(new Code(10002),"李四"); map.put(p1.getCode(), p1); map.put(p2.getCode(), p2); System.out.println("HashMap 中存放的人员信息:\n"+map); //张三改名为张山,***号不变。 Person p3 = new Person(new Code(10001),"张山"); map.put(p3.getCode(), p3); System.out.println("张三改名为张山后 HashMap 中存放的人员信息:\n"+map); //查找***为10001 的人员信息 System.out.println("查找***为:10001 的人员信息:"+map.get(new Code(10001))); } } /** * 人类 * @author Administrator * */ class Person { /** * 每一个**都有一个*** */ private Code code; /** * 姓名 */ private String name; public Code getCode() { return code; } public void setCode(Code code) { this***de = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person() { } public Person(Code code, String name) { this***de = code; this.name = name; } /** * 重写equals()方法 当两个人得***号相同以及姓名相同时,表示这两个人是同一个人。 */ public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Person) { Person p = (Person) o; boolean b = this***de.equals(p***de) && this.name.equals(p.name); return b; } return false; } /** * 重写toString()方法 */ public String toString() { return "【姓名】:" + name + " "; } } 运行结果: HashMap 中存放的人员信息:{【***】:10002=【姓名】:李四 , 【***】:10001=【姓名】:张三 }张三改名为张山后 HashMap 中存放的人员信息:{【***】:10002=【姓名】:李四 , 【***】:10001=【姓名】:张三 , 【***】:10001=【姓名】:张山 }查找***为:10001 的人员信息:null 从上面的结果可以看出: 我们所做的更新和查找操作都失败了。失败的原因就是我们的***类: Code 没有覆写 hashCode() 方法。这个时候,当查找一样的***号码的键值对的时候,使用的是默认的对象的内存地址来进行定位。这样,后面的所有的***号对象 new Code(10001) 产生的 hashCode () 值都是不一样的,所以导致操作失败。 重写Code类的hashcode(),代码上: package com****; import java.util.HashMap; /** * ***类 * * @author ZYD * */ public class Code { /** * ***号码,一旦确定就不能更改 */ private final int id; public int getId() { return id; } /** * 通过构造方法确定***号码 * * @param id */ public Code(int id) { this.id = id; } /** * 重写equals()方法 */ public boolean equals(Object o) { // 如果地址一样,则两个对象相同 if (this == o) { return true; } // 如果两个对象是同一类型,则比较其属性值是否都相同。如果都相同,则说明两个对象也相同;否则,说明这两个对象不相同。 if (o instanceof Code) { Code co = (Code) o; boolean b = (co.id == this.id); return b; } return false; } /** * 重写hashcode()方法,以***号码作为hash码。 * * @return */ public int hashCode() { return id; } /** * 重写toString()方法 */ public String toString() { return "【***】:" + id; } /** * 测试 * @param args */ public static void main(String[] args) { HashMap map = new HashMap(); Person p1 = new Person(new Code(10001),"张三"); Person p2 = new Person(new Code(10002),"李四"); map.put(p1.getCode(), p1); map.put(p2.getCode(), p2); System.out.println("HashMap 中存放的人员信息:\n"+map); //张三改名为张山,***号不变。 Person p3 = new Person(new Code(10001),"张山"); map.put(p3.getCode(), p3); System.out.println("张三改名为张山后 HashMap 中存放的人员信息:\n"+map); //查找***为10001 的人员信息 System.out.println("查找***为:10001 的人员信息:"+map.get(new Code(10001))); } } /** * 人类 * @author Administrator * */ class Person { /** * 每一个**都有一个*** */ private Code code; /** * 姓名 */ private String name; public Code getCode() { return code; } public void setCode(Code code) { this***de = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person() { } public Person(Code code, String name) { this***de = code; this.name = name; } /** * 重写equals()方法 当两个人得***号相同以及姓名相同时,表示这两个人是同一个人。 */ public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Person) { Person p = (Person) o; boolean b = this***de.equals(p***de) && this.name.equals(p.name); return b; } return false; } /** * 重写toString()方法 */ public String toString() { return "【姓名】:" + name + " "; } } 运行效果: HashMap 中存放的人员信息:{【***】:10001=【姓名】:张三 , 【***】:10002=【姓名】:李四 }张三改名为张山后 HashMap 中存放的人员信息:{【***】:10001=【姓名】:张山 , 【***】:10002=【姓名】:李四 }查找***为:10001 的人员信息:【姓名】:张山

本文由宠物迷 百科常识栏目发布,非常欢迎各位朋友分享到个人朋友圈,但转载请说明文章出处“java中hashcode什么时候用?怎么用? 求详解

标签:宠物爱好